import Fastify from 'fastify';
import fastifyJwt from '@fastify/jwt';
import fastifyCookie from '@fastify/cookie';
import fastifyCors from '@fastify/cors';
import fastifyHelmet from '@fastify/helmet';
import fastifyRateLimit from '@fastify/rate-limit';

import { config, validateConfig } from './config/index.js';
import { connectDatabase, disconnectDatabase } from './utils/prisma.js';
import prisma from './utils/prisma.js';
import { errorHandler, notFoundHandler } from './middleware/errorHandler.js';
import { logger } from './utils/logger.js';

// 路由
import authRoutes from './routes/auth.js';
import tokenRoutes from './routes/tokens.js';
import userRoutes from './routes/user.js';
import adminRoutes from './routes/admin.js';

/**
 * 创建Fastify应用
 */
async function createApp() {
  const app = Fastify({
    logger: config.env === 'development',
    trustProxy: true,
  });
  
  // 注册Prisma实例
  app.decorate('prisma', prisma);
  
  // 注册插件
  await app.register(fastifyHelmet, {
    contentSecurityPolicy: false,
  });
  
  await app.register(fastifyCors, config.cors);
  
  await app.register(fastifyCookie, {
    secret: config.jwt.secret,
  });
  
  await app.register(fastifyJwt, {
    secret: config.jwt.secret,
    cookie: {
      cookieName: 'refreshToken',
      signed: false,
    },
  });
  
  await app.register(fastifyRateLimit, {
    max: config.rateLimit.max,
    timeWindow: config.rateLimit.timeWindow,
  });
  
  // 健康检查
  app.get('/health', async (request, reply) => {
    return {
      status: 'ok',
      timestamp: new Date().toISOString(),
      uptime: process.uptime(),
    };
  });
  
  // API路由
  app.register(authRoutes, { prefix: '/api/v1/auth' });
  app.register(tokenRoutes, { prefix: '/api/v1/tokens' });
  app.register(userRoutes, { prefix: '/api/v1/user' });
  app.register(adminRoutes, { prefix: '/api/v1/admin' });
  
  // 错误处理
  app.setErrorHandler(errorHandler);
  app.setNotFoundHandler(notFoundHandler);
  
  return app;
}

/**
 * 启动服务器
 */
async function start() {
  try {
    // 验证配置
    validateConfig();
    logger.info('✓ Configuration validated');
    
    // 连接数据库
    await connectDatabase();
    
    // 检查是否需要创建初始管理员
    await checkAndCreateInitialAdmin();
    
    // 创建应用
    const app = await createApp();
    
    // 启动服务器
    await app.listen({
      port: config.port,
      host: config.host,
    });
    
    logger.info(`✓ Server running at http://${config.host}:${config.port}`);
    logger.info(`✓ Environment: ${config.env}`);
    
    // 优雅关闭
    const signals = ['SIGINT', 'SIGTERM'];
    signals.forEach(signal => {
      process.on(signal, async () => {
        logger.info(`${signal} received, shutting down gracefully...`);
        await app.close();
        await disconnectDatabase();
        process.exit(0);
      });
    });
    
  } catch (error) {
    logger.error('Failed to start server:', error);
    process.exit(1);
  }
}

/**
 * 检查并创建初始管理员
 */
async function checkAndCreateInitialAdmin() {
  try {
    const adminCount = await prisma.user.count({
      where: { role: 'admin' },
    });
    
    if (adminCount === 0) {
      logger.info('No admin user found, creating initial admin...');
      
      const { hashPassword, generateSalt } = await import('./utils/crypto.js');
      
      const admin = await prisma.user.create({
        data: {
          username: config.initialAdmin.username,
          email: config.initialAdmin.email,
          passwordHash: await hashPassword(config.initialAdmin.password),
          masterKeySalt: generateSalt(),
          role: 'admin',
        },
      });
      
      // 创建默认偏好设置
      await prisma.userPreference.create({
        data: { userId: admin.id },
      });
      
      logger.info('✓ Initial admin created successfully');
      logger.info(`   Username: ${admin.username}`);
      logger.info(`   Email: ${admin.email}`);
      logger.warn(`   ⚠️  Please change the default password immediately!`);
    }
  } catch (error) {
    logger.error('Failed to create initial admin:', error);
  }
}

// 启动应用
start();


